/* eslint-disable react/react-in-jsx-scope */
// import fetch from 'umi'; 
import { Modal, message, Row } from 'antd';
import { fetch } from 'umi-request';
import { getCookie, clearCookie, setCookie } from '@/utils/utils'
import { DEFAULT_URL_AUTH, DEFAULT_RESPONE_SUCCESS } from '@/constants';
import responseText from './responseText';

let timer = null;

function debounce(fn, delay, isImmediate) {
  let timer = null; // 初始化timer，作为计时清除依据
  return () => {
    let context = this; // 获取函数所在作用域this
    // eslint-disable-next-line prefer-rest-params
    let args = arguments; // 取得传入参数
    clearTimeout(timer);
    if (isImmediate && timer === null) {
      // 时间间隔外立即执行
      fn.apply(context, args);
      timer = 0;
      return;
    }
    // eslint-disable-next-line func-names
    timer = setTimeout(() => {
      fn.apply(context, args);
      timer = null;
    }, delay);
  }
}

function parseJSON(response) {
  const resTextList = responseText;
  let isContain = false;
  resTextList.map(item => {
    if (response.url.indexOf(item) !== -1) {
      isContain = true
    }
  })
  // 当接口返回的是文本格式时，返回text
  if (isContain) {
    return response.text();
  }
  if (response && response.headers && response.headers.get('content-type') &&
    (response.headers.get('content-type').indexOf('application/vnd.ms-excel') !== -1 || response.headers.get('content-type').indexOf('application/octet-stream') !== -1)) {
    return response.blob();
  }
  // if (response && response.headers && response.headers.has('x-total-count')) {
  //   const total = response.headers.get('x-total-count');
  //   return response.json().then((response) => {
  //     if (response.total) {
  //       return response;
  //     }
  //     return { data: response, total };
  //   }).catch(err => { console.error(e); return {} });
  // }
  // return response.json().then((result) => result).catch(err => { console.error(err); return {} });
  return response
    .json()
    .then((result) => {
      if (response && response.headers && response.headers.has('x-total-count')) {
        if (Array.isArray(result)) {
          return result.map(item => ({ ...item, total: response.headers.get('x-total-count') }));
        }
        return { ...result, total: response.headers.get('x-total-count') }
      }
      return result;
    })
    .catch(err => {
      console.info(err);
      return {};
    });
}

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  }

  const error = new Error(response.statusText);
  error.name = response.status;
  error.response = response;
  throw error;
}

function isPromise(obj) {
  return (
    !!obj &&
    (typeof obj === 'object' || typeof obj === 'function') &&
    typeof obj.then === 'function'
  );
}

function handleError401(url, options, isLogout, response, dispatch) {
  // 用户尚未登录
  if (!getCookie('role')) {
    const t = response.json();
    if (isPromise(t)) {
      t.then(result => {
        if (typeof dispatch === 'function') {
          const { onError } = options;

          if (typeof onError === 'function') {
            onError();
          }
          dispatch({
            type: 'login/changeState',
            payload: { loginError: result.message ? result.message : result && result.result ? result.result.msg : '' }
          });
        }
      });
    }
  }
  // 用户已登录
  else if (isLogout) {
    if (!timer) {
      // eslint-disable-next-line func-names
      timer = setTimeout(() => {
        logout();
        timer = null;
      }, 1000);
    }
  } else {
    const refreshOption = {
      method: 'POST',
      headers: {
        Token: getCookie('refresh_token')
      }
    };
    return request(`${DEFAULT_URL_AUTH}/token/refresh`, refreshOption, true).then(refreshResponse => {
      if (refreshResponse) {
        if (refreshResponse.status === DEFAULT_RESPONE_SUCCESS) {
          setCookie('access_token', refreshResponse.result.access_token);
          setCookie('refresh_token', refreshResponse.result.refresh_token);
          return request(url, options, true);
        }
        return debounce(logout, 1000);
      }
    });
  }
}

function logout(dispatch) {
  Modal.warning({
    maskClosable: true,
    title: 'Token失效或已过期，系统将退出!',
    okText: '确定',
    onOk: () => {
      // dispatch({ type: 'global/logout', payload: { noCall: true } });
      clearAllCookie();
    },
    onCancel: () => {
      // dispatch({ type: 'global/logout', payload: { noCall: true } });
      clearAllCookie();
    },
  });
}

function clearAllCookie() {
  clearCookie('role');
  clearCookie('metabase.SESSION');
  clearCookie('access_token');
  clearCookie('authority');
  clearCookie('refresh_token');
  clearCookie('username');
  clearCookie('displayName');
  window.location.href = '/#/user/login';
}

/**
 * Requests a URL, returning a promise.
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch"
 * @return {object}           An object containing either "data" or "err"
 */
export default function request(url, options = {}, isLogout, type) {
  const defaultOptions = {
    mode: 'cors',
    // credentials: 'omit'
  };
  const newOptions = { ...defaultOptions, ...options };
  if ((newOptions.method === 'POST' || newOptions.method === 'PUT') && !(newOptions.body instanceof FormData)) {
    newOptions.headers = {
      Accept: 'application/json',
      'Content-Type': 'application/json; charset=utf-8',
      ...newOptions.headers
    };
    if (newOptions.headers && newOptions.headers.Accept === 'application/json') {
      newOptions.body = JSON.stringify(newOptions.body);
    }
  }
  if (newOptions.body instanceof FormData) {
    newOptions.headers = {
      Accept: 'text/javascript, text/html, application/xml, text/xml, */*',
      ...newOptions.headers
    };
  }
  if (getCookie('role')) {
    newOptions.headers = {
      Token: getCookie('access_token'),
      ...newOptions.headers
    }
  }

  return fetch(url, newOptions)
    .then(checkStatus)
    .then(parseJSON)
    .catch(err => {
      const { dispatch } = newOptions;
      const { name: status, response } = err;

      if (response) {
        if (status === 401) {
          return handleError401(url, options, isLogout, response, dispatch);
        } else {
          if (response.statusText === 'Internal Server Error') {
            message.error(`操作失败：Internal Server Error`, 3);
          } else {
            try {
              const t = response.json();
              if (isPromise(t)) {
                t.then(result => {
                  const content = (
                    <span style={{ display: 'inline-block' }}>
                      <Row>操作失败：{result.message}</Row>
                      <Row>{result.title}</Row>
                      <Row>{result.detail}</Row>
                    </span>)
                  // 操作失败：${result.message}\n${result.title}\n${ result.detail }
                  message.error(content, 3);
                });
              }
            } catch (e) {
              console.error(e);
            }
          }
        }
        return;
      }
      message.error(`操作失败：${err}`, 3);
    });
}
